package com.yuedou.api.service.wxuser.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yuedou.api.dao.platform.SplitAccountMapper;
import com.yuedou.api.dao.platform.SplitAccountRecordMapper;
import com.yuedou.api.dao.wxuser.UserMapper;
import com.yuedou.api.dao.wxuser.UserMpMapper;
import com.yuedou.api.entity.platform.*;
import com.yuedou.api.entity.wxuser.User;
import com.yuedou.api.entity.wxuser.UserMp;
import com.yuedou.api.exception.TransactionalException;
import com.yuedou.api.service.base.impl.BaseServiceImpl;
import com.yuedou.api.service.platfom.*;
import com.yuedou.api.service.wxuser.UserService;
import com.yuedou.api.util.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private UserMpMapper userMpMapper;
    @Resource
    private ParameterService parameterService;
    @Resource
    protected RedisTemplate<String, Object> redisTemplate;
    @Resource
    private WxTemplateService wxTemplateService;
    @Resource
    private SplitAccountMapper splitAccountMapper;

    @Value("${web.uploadPath}")
    private String uploadPath;

    @Override
    @Transactional
    public User register(String openId, String unionId,String sessionKey,String token,Integer ag_id,String platform,int promoter_id,double lng,double lat, String from_type) throws TransactionalException {
        User user = new User();
        int ret = 0;
        try{
            Parameter parameter = parameterService.getParameterById(1);
            if(parameter != null){
                user.setOpenId(openId);
                user.setUnionId(unionId);
                user.setCreateTime(new Date());
                user.setLastActiveTime(new Date());
                user.setSessionKey(sessionKey);
                user.setUserType(0);
                user.setIsAdmin(0);
                user.setToken(token);
                user.setLng(new BigDecimal(lng));
                user.setLat(new BigDecimal(lat));
                user.setPlatform(platform);
                user.setFaceUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/POgEwh4mIHO4nibH0KlMECNjjGxQUq24ZEaGT4poC6icRiccVGKSyXwibcPq4BWmiaIGuG1icwxaQX6grC9VemZoJ8rg/132");

                ret = userMapper.insert(user);
                if(ret <= 0){
                    throw new TransactionalException("userMapper insert error");
                }


                SplitAccount splitAccount = new SplitAccount();
                splitAccount.setAccountType(4);
                splitAccount.setUserId(user.getId());
                splitAccount.setAccountId(user.getId());
                splitAccount.setSplitMoney(new BigDecimal(0));
                splitAccount.setFreezen(new BigDecimal(0));
                splitAccount.setChargerMoney(new BigDecimal(0));
                splitAccount.setGoldenMoney(0L);
                splitAccount.setChargerMoney(new BigDecimal(0));
                splitAccount.setVipAccountMoney(new BigDecimal(0));
                splitAccount.setCashMoneyPool(new BigDecimal(0));
                ret = splitAccountMapper.insert(splitAccount);
                if(ret <= 0){
                    throw new TransactionalException("merMapper insert error");
                }

                if (StrUtil.isEmpty(user.getQrCode())) {
                    try {
                        String qrCode = "";
                        String fileName = "user_qr_" + user.getId() + ".jpg";
                        String content = "https://www.sdyuedou.com/wxmini/user/qr?type=user&ag_id=" + user.getId();
                        int upload_type = OssUtil.TYPE_USER_QRCODE_PHOTOS;
                        System.out.println("content:  " + content);
                        String img_key = OssUtil.getUploadPrefix(upload_type) + fileName;
                        QRCodeUtilEx.createQrCodeImg(content, "",
                                null, uploadPath + "/" + img_key, true,fileName,upload_type);
                        qrCode = img_key;
                        user.setQrCode(qrCode);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }

                String userNo = "24" + String.format("%06d", user.getId());
                user.setNickName("用户" + user.getId());
                user.setUserNo(userNo);
                ret = userMapper.updateById(user);
                if(ret <= 0){
                    throw new TransactionalException("userMapper insert error");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("register system error");
        }
        return user;
    }

    @Override
    @Transactional
    public int bandPhone(String phone, User user) throws TransactionalException {
        try{
            int ret = 0;
            Map<String,Object> map = new HashMap<>();
            map.put("userType",user.getUserType());
            map.put("phoneNum",phone);
            user.setPhoneNum(phone);
            ret = userMapper.updateById(user);
            if(ret <= 0){
                throw new TransactionalException("userMapper updateById  error");
            }

            return ret;
        }catch (TransactionalException ex){
            throw new TransactionalException("bandShop system error");
        }
    }

    @Override
    public int unBandPhone(String phone, User user) throws TransactionalException {
        try{
            int ret = 0;
            Map<String,Object> map = new HashMap<>();
            map.put("userType",user.getUserType());
            map.put("phoneNum",phone);

            user.setPhoneNum("");
            ret = userMapper.updateById(user);
            if(ret <= 0){
                throw new TransactionalException("userMapper updateById  error");
            }
            return ret;
        }catch (TransactionalException ex){
            throw new TransactionalException("bandShop system error");
        }
    }

    @Override
    public List<User> selectByShopId(Integer shop_id, Integer user_id, Integer offset, Integer pageSize, Date begin_time, Date end_time) {
        return userMapper.selectByShopId(shop_id,user_id,offset,pageSize,begin_time,end_time);
    }
    
    @Override
    @Transactional
    public int updateLogin(User user) throws TransactionalException {
        int ret = 0;
        try{

            if (StrUtil.isEmpty(user.getQrCode())) {
                try {
                    String qrCode = "";
                    String fileName = "user_qr_" + user.getId() + ".jpg";
                    String content = "https://www.sdyuedou.com/wxmini/user/qr?type=user&ag_id=" + user.getId();
                    int upload_type = OssUtil.TYPE_USER_QRCODE_PHOTOS;
                    System.out.println("content:  " + content);
                    String img_key = OssUtil.getUploadPrefix(upload_type) + fileName;
                    QRCodeUtilEx.createQrCodeImg(content, "",
                            null, uploadPath + "/" + img_key, true,fileName,upload_type);
                    qrCode = img_key;
                    user.setQrCode(qrCode);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }

            String userNo = "22" + String.format("%06d", user.getId());
            user.setUserNo(userNo);
            if(StrUtil.isEmpty(user.getNickName())){
                user.setNickName("用户" + user.getId());
            }
            ret = userMapper.updateById(user);
            if(ret <= 0){
                throw new TransactionalException("userMapper insert error");
            }

            QueryWrapper<SplitAccount> qwAccount = new QueryWrapper<>();
            qwAccount.eq("user_id",user.getId());
            qwAccount.eq("account_type", 4);
            qwAccount.last("limit 1");
            SplitAccount splitAccount = splitAccountMapper.selectOne(qwAccount);
            if(splitAccount == null){
                splitAccount = new SplitAccount();
                splitAccount.setAccountType(4);
                splitAccount.setUserId(user.getId());
                splitAccount.setAccountId(user.getId());
                splitAccount.setSplitMoney(new BigDecimal(0));
                splitAccount.setFreezen(new BigDecimal(0));
                splitAccount.setChargerMoney(new BigDecimal(0));
                splitAccount.setGoldenMoney(0L);
                splitAccount.setChargerMoney(new BigDecimal(0));
                splitAccount.setVipAccountMoney(new BigDecimal(0));
                ret = splitAccountMapper.insert(splitAccount);
                if(ret <= 0){
                    throw new TransactionalException("splitAccountMapper insert error");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("register system error");
        }
        return ret;
    }

    @Override
    public int reloadUserMp(String nextOpenId) {
//        String accessToken = WxMessage.getACCESSTOKEN(appidMp,secretMp);
//        String access_token = redisTemplate.opsForValue().get("access_token_mp")!=null ? redisTemplate.opsForValue().get("access_token_mp").toString() : null;
//        if(StrUtil.isEmpty(access_token)){
//            access_token = WxMessage.getACCESSTOKEN(appidMp,secretMp);
//            redisTemplate.opsForValue().set("access_token_mp",access_token,3600L, TimeUnit.SECONDS);
//        }
        String access_token = wxTemplateService.getAccessToken(0);// WxMessage.getACCESSTOKEN(appidMp,secretMp);

//        System.out.println("accessToken:" + access_token);
        JSONObject jsonObject = WxMessage.getUserMp(access_token,nextOpenId);
        if(jsonObject != null){
//            System.out.println("同步公众号用户： " + jsonObject.toString());
            if(jsonObject.containsKey("data") && jsonObject.getJSONObject("data").containsKey("openid")){
                JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("openid");
                if(jsonArray != null && jsonArray.size() > 0) {
                    for (int i = 0; i < jsonArray.size(); i++) {
                        String openid = jsonArray.getStr(i);
                        JSONObject userInfo = WxMessage.getUserMpInfo(access_token,openid);
                        if(userInfo!=null && userInfo.size() > 0){
                            String openId = userInfo.getStr("openid");
                            String unionId = userInfo.getStr("unionid");
                            if(StrUtil.isNotEmpty(openId) && StrUtil.isNotEmpty(unionId)) {
                                UserMp userMp = userMpMapper.selectOneByColumn("union_id", unionId);
                                if (userMp == null) {
                                    userMp = new UserMp();
                                    userMp.setOpenId(openId);
                                    userMp.setUnionId(unionId);
                                    userMp.setCreateTime(new Date());
                                    userMpMapper.insert(userMp);
                                }
//                                else {
//                                    userMp.setLastUpdateTime(new Date());
//                                    userMpMapper.updateById(userMp);
//                                }
                            }
                        }
                    }
                }
            }
        }
        return 1;
    }


    @Override
    public User getLocationInfo(User user) {
        boolean addressFlag = StrUtil.isEmpty(user.getProvince()) || StrUtil.isEmpty(user.getDistrict()) || StrUtil.isEmpty(user.getCity());
        boolean latitudeFlag = !user.getLng().equals(BigDecimal.ZERO) && !user.getLat().equals(BigDecimal.ZERO);
        if (addressFlag && latitudeFlag) {
            JSONObject locationInfo = BaiduMapUtils.getLocationInfo(user.getLat().toString(), user.getLng().toString());
            int status = locationInfo.getInt("status");
            if (status != 0) {
                return user;
            }
            String province = locationInfo.getJSONObject("result").getJSONObject("addressComponent").getStr("province");
            String city = locationInfo.getJSONObject("result").getJSONObject("addressComponent").getStr("city");
            String district = locationInfo.getJSONObject("result").getJSONObject("addressComponent").getStr("district");
            user.setProvince(province);
            user.setCity(city);
            user.setDistrict(district);
        }
        return user;
    }

    @Override
    public Map<String,Object> validateLocation(User user) {
        Map<String,Object> map = new HashMap<>();
        String address = "";
        boolean bl = false;
        if(user.getLng()!=null && user.getLat()!=null){
            boolean latitudeFlag = !user.getLng().equals(BigDecimal.ZERO) && !user.getLat().equals(BigDecimal.ZERO);
            if(latitudeFlag){
                JSONObject locationInfo = BaiduMapUtils.getLocationInfo(user.getLat().toString(), user.getLng().toString());
                int status = locationInfo.getInt("status");
                if(status == 0){
                    String province = locationInfo.getJSONObject("result").getJSONObject("addressComponent").getStr("province");
                    String city = locationInfo.getJSONObject("result").getJSONObject("addressComponent").getStr("city");
                    String district = locationInfo.getJSONObject("result").getJSONObject("addressComponent").getStr("district");

                    address = province + city + district;
                    //不为空的情况下
                    if(StrUtil.isNotEmpty(user.getProvince()) && StrUtil.isNotEmpty(user.getDistrict()) && StrUtil.isNotEmpty(user.getCity())){
                        if(!user.getProvince().equals(province) || !user.getCity().equals(city) || !user.getDistrict().equals(district) ){
                            bl = false;
                        }else{
                            bl = true;
                        }
                    }
                }
            }
        }
        map.put("is_change_location", bl ? 0 : 1);
        map.put("location_address", address);
        return map;
    }
}
